package org.zero.jjwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodec;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.experimental.UtilityClass;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Map;

/**
 * @author Zero (cnzeropro@qq.com)
 * @date 2021/11/24 11:19
 */
@UtilityClass
public class JjwtUtil {
    /**
     * 主题
     */
    private final String SUBJECT = "USER_TOKEN";

    /**
     * 签名算法
     */
    private final SignatureAlgorithm ALGORITHM = SignatureAlgorithm.HS256;

    /**
     * 签名秘钥
     */
    private final String SIGN_KEY = "abc123";

    /**
     * 压缩规则
     */
    private final CompressionCodec COMPRESSION_CODECS = CompressionCodecs.DEFLATE;

    /**
     * 过期时间，单位毫秒
     */
    private final long EXPIRATION = 24 * 60 * 60 * 1000L;

    /**
     * 根据参数生成token
     *
     * @param map
     * @return
     */
    public String createToken(Map<String, Object> map) {

        return Jwts.builder()
                .setSubject(SUBJECT)
                .signWith(ALGORITHM, SIGN_KEY)
                .setClaims(map)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .setNotBefore(new Date())
                .compressWith(COMPRESSION_CODECS)
                .compact();
    }

    /**
     * 根据token字符串得到信息
     *
     * @param token
     * @return
     */
    public <T> T getValue(String token, String key, Class<T> clazz) {
        if (!StringUtils.hasText(token)) {
            return null;
        }

        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SIGN_KEY).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        return claims.get(key, clazz);
    }

    public boolean isExpired(String token) {
        if (!StringUtils.hasText(token)) {
            return false;
        }

        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SIGN_KEY).parseClaimsJws(token);
        Date expiration = claimsJws.getBody().getExpiration();
        return expiration.before(new Date());
    }
}
